/**
 * @desc 函数防抖
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param immediate true 表立即执行，false 表非立即执行
 * 
 * 默认选择立即执行版本
 * 立即执行版的意思是触发事件后函数会立即执行，然后 n 秒内不触发事件才能继续执行函数的效果。
 */

export function debounce(fn: any, wait: any, immediate = false) {
  let timer: any, startTimeStamp = 0;
  let context: any, args: any;
  let run = (timerInterval: any) => {
    timer = setTimeout(() => {
      let now = (new Date()).getTime();
      let interval = now - startTimeStamp
      if (interval < timerInterval) { // the timer start time has been reset，so the interval is less than timerInterval
        startTimeStamp = now;
        run(wait - interval);  // reset timer for left time 
      } else {
        if (!immediate) {
          fn.apply(context, args);
        }
        clearTimeout(timer);
        timer = null;
      }
    }, timerInterval);
  }

  return function (_data?: any) {
    // @ts-ignore
    context = this;
    args = arguments;
    let now = (new Date()).getTime();
    startTimeStamp = now; // set timer start time
    if (!timer) {
      if (immediate) {
        fn.apply(context, args);
      }
      run(wait);    // last timer alreay executed, set a new timer
    }
  }
}


/**
 * @desc function 需要节流的函数
 * wait [number] 毫秒 执行间隔时间
 * */
export function throttle(fn: any, wait: any, immediate?: any) {
  let timer: any, timeStamp = 0;
  let context: any, args: any;
  let run = () => {
    timer = setTimeout(() => {
      if (!immediate) {
        fn.apply(context, args);
      }
      clearTimeout(timer);
      timer = null;
    }, wait);
  }
  return function (_data?: any) {
    // @ts-ignore
    context = this;
    args = arguments;
    if (!timer) {
      if (immediate) {
        fn.apply(context, args);
      }
      run();
    } else {
      console.log("throttle, ignore");
    }
  }
}